package com.yfq.springframework.beans.factory;

import com.yfq.springframework.beans.BeansException;
import com.yfq.springframework.beans.PropertyValue;
import com.yfq.springframework.beans.PropertyValues;
import com.yfq.springframework.beans.config.BeanDefinition;
import com.yfq.springframework.beans.config.BeanFactoryPostProcessor;
import com.yfq.springframework.core.io.DefaultResourceLoader;
import com.yfq.springframework.core.io.Resource;
import com.yfq.springframework.core.io.ResourceLoader;

import java.io.IOException;
import java.util.Properties;

/**
 * @author 姚凤桥
 * @date 2023/2/4 19:56
 * @description 在BeanDefinition加载完毕，对象实例化之前，处理BeanDefinition中的占位符，替换为对应的值
 */
public class PropertyPlaceholderConfigurer implements BeanFactoryPostProcessor {
    public static final String PROPERTY_PLACEHOLDER_PREFIX = "${";

    public static final String PROPERTY_PLACEHOLDER_SUFFIX = "}";

    /**
     * 配置文件路径
     */
    private String location;

    @Override
    public void postProcessorBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        try {
            //加载配置文件
            ResourceLoader resourceLoader = new DefaultResourceLoader();
            Resource resource = resourceLoader.getResource(location);
            Properties properties = new Properties();
            properties.load(resource.getInputStream());

            //获取BeanDefinition，如果PropertyValues中有需要替换的值，就在配置文件中寻找对应的配置来替换
            String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
            for (String beanName : beanDefinitionNames) {
                BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
                PropertyValues propertyValues = beanDefinition.getPropertyValues();
                for (PropertyValue propertyValue : propertyValues.getPropertyValues()) {
                    String name = propertyValue.getName();
                    Object value = propertyValue.getValue();
                    if (!(value instanceof String)) {
                        continue;
                    }

                    String valueStr = (String) value;
                    int startIndex = valueStr.indexOf(PROPERTY_PLACEHOLDER_PREFIX) + 2;
                    int endIndex = valueStr.indexOf(PROPERTY_PLACEHOLDER_SUFFIX);
                    if (startIndex != 1 && startIndex != endIndex) {
                        String key = valueStr.substring(startIndex, endIndex);
                        String property = properties.getProperty(key);
                        propertyValues.addPropertyValue(new PropertyValue(name, property));
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw new BeansException("Could not load properties" + e);
        }
    }

    public void setLocation(String location) {
        this.location = location;
    }
}


